package com.wcy.controller.user;

import com.wcy.entity.LearningResource;
import com.wcy.entity.ResourceTag;
import com.wcy.entity.User;
import com.wcy.entity.pageVo.ApiDescriptor;
import com.wcy.entity.pageVo.ColumnConstructor;
import com.wcy.entity.pageVo.PageData;
import com.wcy.entity.result.ChartElement;
import com.wcy.entity.result.RatingResult;
import com.wcy.entity.userVo.AuthorProfile;
import com.wcy.entity.userVo.PasswordObject;
import com.wcy.entity.userVo.UserFiltered;
import com.wcy.feign.resource.FeignLearningResourceService;
import com.wcy.feign.resource.FeignResourceTagService;
import com.wcy.feign.user.FeignUserRatingService;
import com.wcy.feign.user.FeignUserService;
import jakarta.annotation.Resource;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

@RestController
public class UserController {
    @Resource
    private FeignUserService feignUserService;
    @Resource
    private FeignLearningResourceService feignLearningResourceService;
    @Resource
    private FeignUserRatingService feignUserRatingService;
    @Resource
    private FeignResourceTagService feignResourceTagService;

    @GetMapping("user/page")
    public ResponseEntity<PageData<User>> getPage(@RequestParam(defaultValue = "1") int pageNum,
                                                  @RequestParam(defaultValue = "10") int pageSize) {
        return ResponseEntity.ok(new PageData<>(User.class, Objects.requireNonNull(feignUserService.getPage(pageNum, pageSize).getBody()),  new ApiDescriptor("user/add", "user/update", "user/delete"), ColumnConstructor.create()));
    }

    @GetMapping("user/list")
    public ResponseEntity<List<User>> getList() {
        return ResponseEntity.ok(feignUserService.getList().getBody());
    }

    @PostMapping("user/add")
    public ResponseEntity<Void> add(@RequestBody User user) {
        return feignUserService.add(user);
    }

    @PutMapping("user/update")
    public ResponseEntity<Void> update(@RequestBody User user) {
        return feignUserService.update(user);
    }

    @DeleteMapping("user/delete/{id}")
    public ResponseEntity<Void> delete(@PathVariable Integer id) {
        return feignUserService.delete(id);
    }

    @PutMapping("user/updateProfile")
    public ResponseEntity<UserFiltered> updateProfile(@RequestBody User user){
        return feignUserService.updateProfile(user);
    }

    @GetMapping("user/getProfile")
    public ResponseEntity<UserFiltered> getProfile(){
        return feignUserService.getProfile();
    }

    @GetMapping("user/{id}")
    public ResponseEntity<UserFiltered> getUser(@PathVariable("id") Integer id){
        return feignUserService.getUser(id);
    }

    @GetMapping("user/authorProfile/{id}")
    public ResponseEntity<AuthorProfile> getAuthorProfile(@PathVariable("id") Integer id){
        List<LearningResource> resources = feignLearningResourceService.getByAuthor(id).getBody();
        assert resources != null;
        List<Integer> resourceIds = resources.stream().map(LearningResource::getResourceId).collect(Collectors.toList());
        System.out.println("test:"+resourceIds);
        return feignUserService.getAuthorProfile(resourceIds);
    }

    @GetMapping("user/author/resourceRank/{id}")
    public ResponseEntity<List<ChartElement>> getAuthorResourceRank(@PathVariable("id") Integer id){
        List<LearningResource> resources = feignLearningResourceService.getByAuthor(id).getBody();
        assert resources != null;
        Map<String,Double> resourceRank = new HashMap<>();
        for(LearningResource resource:resources){
            ResponseEntity<RatingResult> ratingResult = feignUserRatingService.getByResourceId(resource.getResourceId());
            resourceRank.put(resource.getTitle(), Objects.requireNonNull(ratingResult.getBody()).getRatingScore());
        }
        List<ChartElement> rank = resourceRank.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()
                )).map(entry -> new ChartElement(entry.getKey(), entry.getValue())).collect(Collectors.toList());
        if(rank.size()>7)
            rank = rank.subList(0,7);
        return ResponseEntity.ok(rank);
    }

    @GetMapping("user/author/resourceTagCount/{id}")
    public ResponseEntity<List<ChartElement>> getAuthorResourceTagCount(@PathVariable("id") Integer id){
        List<LearningResource> resources = feignLearningResourceService.getByAuthor(id).getBody();
        assert resources != null;
        Map<String,Integer> resourceTagCount = new HashMap<>();
        for(LearningResource resource:resources){
            List<ResourceTag> tagMappings = feignResourceTagService.getByResourceId(resource.getResourceId()).getBody();
            assert tagMappings != null;
            for(ResourceTag tagMapping:tagMappings){
                resourceTagCount.put(tagMapping.getTagName(),resourceTagCount.getOrDefault(tagMapping.getTagName(),0)+1);
            }
        }
        List<ChartElement> countList = resourceTagCount.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()
        )).map(entry -> new ChartElement(entry.getKey(), entry.getValue().doubleValue())).collect(Collectors.toList());
        return ResponseEntity.ok(countList);
    }

    @GetMapping("user/isAuthor")
    public ResponseEntity<Boolean> hasAuthor(){
        return feignUserService.hasAuthor();
    }

    @PostMapping("user/becomeAuthor")
    public ResponseEntity<Boolean> becomeAuthor(){
        return feignUserService.becomeAuthor();
    }

    @PostMapping("user/alterPassword")
    public ResponseEntity<String> alterPassword(@RequestBody PasswordObject passwordObject){
        if(passwordObject.getOldPassword().isEmpty()||passwordObject.getNewPassword().isEmpty()||passwordObject.getConfirmPassword().isEmpty())
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("请输入完整信息");
        if(passwordObject.getOldPassword().equals(passwordObject.getNewPassword()))
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("新密码与旧密码相同");
        if(!passwordObject.getNewPassword().equals(passwordObject.getConfirmPassword()))
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("两次输入的密码不一致");
        return feignUserService.alterPassword(passwordObject);
    }
}
